#include <iostream>
#include <fstream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#include "MyQueue.h"

#define PORT 8888
#define WAV_HEADER_SIZE 44



void receive_udp_message(int port) 
{
    printf("-------------------0220\n");
    // 创建 UDP 套接字
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        std::cerr << "Failed to create socket" << std::endl;
        return;
    }

    // 设置服务器地址
    struct sockaddr_in serverAddr;
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    serverAddr.sin_port = htons(port);

    // 绑定套接字到指定地址和端口
    if (bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
        std::cerr << "Failed to bind socket" << std::endl;
        close(sockfd);
        return;
    }

    std::cout << "等待接收消息..." << std::endl;

    char buffer[RECV_BUFF_SIZE];
    struct sockaddr_in clientAddr;
    socklen_t clientAddrLen = sizeof(clientAddr);

    // 接收消息
    ssize_t recvBytes = recvfrom(sockfd, buffer, RECV_BUFF_SIZE, 0, (struct sockaddr*)&clientAddr, &clientAddrLen);
    if (recvBytes < 0) {
        std::cerr << "Failed to receive message" << std::endl;
    } else {
        buffer[recvBytes] = '\0';
        std::cout << "接收到消息: " << buffer << std::endl;
    }

    // 关闭套接字
    close(sockfd);
}

void* UdpRecvDataToBuff(void* recvListParm)
{
    AudioRecvAllSt* recvAllstObj = static_cast<AudioRecvAllSt*>(recvListParm);

    printf("UdpRecvDataToBuff() 2025 03 01 (10000 days)\n");
    // 创建 UDP 套接字
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        std::cerr << "Failed to create socket" << std::endl;
        return (void *)-1;
    }

    // 设置服务器地址
    struct sockaddr_in serverAddr;
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    serverAddr.sin_port = htons(PORT);

    // 绑定套接字到指定地址和端口
    if (bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
        std::cerr << "Failed to bind socket" << std::endl;
        close(sockfd);
        return (void *)-1;
    }

    // 接收文件大小信息
    char buffer[RECV_BUFF_SIZE];
    struct sockaddr_in clientAddr;
    socklen_t clientAddrLen = sizeof(clientAddr);
    ssize_t recvBytes = recvfrom(sockfd, buffer, RECV_BUFF_SIZE, 0, (struct sockaddr*)&clientAddr, &clientAddrLen);
    if (recvBytes < 0) 
    {
        std::cerr << "Failed to receive file size" << std::endl;
        close(sockfd);
        return (void *)-1;
    }

    printf("after recvfrom() recvBytes = %ld, Source Ip = %s\n", recvBytes, inet_ntoa(clientAddr.sin_addr));
    memcpy(&(recvAllstObj->wavHeaderObj), buffer, recvBytes);
    

    buffer[recvBytes] = '\0';
    size_t fileSize = std::stoul(std::string(buffer));

    printf("recv data fileSize = %ld\n", fileSize);
    AudioRecvItemSt item;

    // 接收 WAV 文件头部
    recvBytes = recvfrom(sockfd, buffer, WAV_HEADER_SIZE, 0, (struct sockaddr*)&clientAddr, &clientAddrLen);
    if (recvBytes < 0) 
    {
        std::cerr << "Failed to receive WAV header" << std::endl;
        close(sockfd);
        return (void *)-1;
    }

    memcpy(&(recvAllstObj->wavHeaderObj), buffer, sizeof(recvAllstObj->wavHeaderObj));
    recvAllstObj->bIsReceiving = true;
    

    size_t receivedSize = WAV_HEADER_SIZE;
    while (receivedSize < fileSize) 
    {
        memset(&item, 0, sizeof(item));
        memset(buffer, 0, sizeof(buffer));
        recvBytes = recvfrom(sockfd, buffer, RECV_BUFF_SIZE, 0, (struct sockaddr*)&clientAddr, &clientAddrLen);
        if (recvBytes < 0) 
        {
            std::cerr << "Failed to receive data" << std::endl;
            break;
        }
        receivedSize += recvBytes;

        item.buffLen = recvBytes;
        memcpy(item.buff, buffer, recvBytes);

        printf("calling InsQueue() recvBytes = %d\n", recvBytes);
        InsQueue(&(recvAllstObj->recvList), item);
        // printf("this time recvBytes %d, percent = %d %%\n", recvBytes, receivedSize * 100 / fileSize);
    }

    close(sockfd);


    if (receivedSize == fileSize) 
    {
        std::cout << "WAV 文件接收完成。" << std::endl;
    } 
    else 
    {
        std::cerr << "文件接收不完整。" << std::endl;
    }

}


int UdpRecvWavFile() 
{
    // 创建 UDP 套接字
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        std::cerr << "Failed to create socket" << std::endl;
        return -1;
    }

    // 设置服务器地址
    struct sockaddr_in serverAddr;
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    serverAddr.sin_port = htons(PORT);

    // 绑定套接字到指定地址和端口
    if (bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
        std::cerr << "Failed to bind socket" << std::endl;
        close(sockfd);
        return -1;
    }

    // 接收文件大小信息
    char buffer[RECV_BUFF_SIZE];
    struct sockaddr_in clientAddr;
    socklen_t clientAddrLen = sizeof(clientAddr);
    ssize_t recvBytes = recvfrom(sockfd, buffer, RECV_BUFF_SIZE, 0, (struct sockaddr*)&clientAddr, &clientAddrLen);
    if (recvBytes < 0) 
    {
        std::cerr << "Failed to receive file size" << std::endl;
        close(sockfd);
        return -1;
    }

    printf("after recvfrom() recvBytes = %ld, Source Ip = %s\n", recvBytes, inet_ntoa(clientAddr.sin_addr));



    buffer[recvBytes] = '\0';
    size_t fileSize = std::stoul(std::string(buffer));

    printf("recv data fileSize = %ld\n", fileSize);

    // 打开文件用于写入接收的数据
    std::ofstream outputFile("aaa.wav", std::ios::binary);
    if (!outputFile) {
        std::cerr << "Failed to open output file" << std::endl;
        close(sockfd);
        return -1;
    }

    // 接收 WAV 文件头部
    recvBytes = recvfrom(sockfd, buffer, WAV_HEADER_SIZE, 0, (struct sockaddr*)&clientAddr, &clientAddrLen);
    if (recvBytes < 0) {
        std::cerr << "Failed to receive WAV header" << std::endl;
        outputFile.close();
        close(sockfd);
        return -1;
    }
    outputFile.write(buffer, recvBytes);

    size_t receivedSize = WAV_HEADER_SIZE;
    while (receivedSize < fileSize) {
        recvBytes = recvfrom(sockfd, buffer, RECV_BUFF_SIZE, 0, (struct sockaddr*)&clientAddr, &clientAddrLen);
        if (recvBytes < 0) {
            std::cerr << "Failed to receive data" << std::endl;
            break;
        }
        outputFile.write(buffer, recvBytes);
        receivedSize += recvBytes;
    }

    // 关闭文件和套接字
    outputFile.close();
    close(sockfd);

    if (receivedSize == fileSize) {
        std::cout << "WAV 文件接收完成。" << std::endl;
    } else {
        std::cerr << "文件接收不完整。" << std::endl;
    }

    return 0;
}




int Testmain()
{


    UdpRecvWavFile();
    // receive_udp_message(PORT);

    return 0;
}